﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CSF.BusinessCore.BLL;
using CSF.Customers.Data;
using CSF.Security.Data;
using Ict.DataAccess;
using CSF.Security.BLL;

namespace CSF.Customers.BLL
{
    /// <summary>
    /// 客户业务逻辑类
    /// </summary>
    public class CustomerBLL : TransactionLogic<Customer>
    {
        /// <summary>
        /// 获取指定客户的下属用户集合
        /// </summary>
        /// <param name="customerId">客户Id</param>
        /// <returns>用户集合</returns>
        public List<UserAccount> GetCustomerUsers(int customerId)
        {
            CustomerUserBLL bll = new CustomerUserBLL();
            return bll.GetUserByCustomer(customerId);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="customerId"></param>
        /// <param name="userId"></param>
        /// <param name="createBy"></param>
        /// <returns></returns>
        public bool JoinCustomerUser(int customerId, int userId, string createBy)
        {
            CustomerUser obj = new CustomerUser()
            {
                CustomerId = customerId,
                UserId = userId,
                CreateBy = createBy
            };
            CustomerUserBLL bll = new CustomerUserBLL();
            return bll.Insert(obj);
        }

        /// <summary>
        /// 获取指定用户对应的通过审核的客户集合
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <returns>客户集合</returns>
        public List<Customer> GetByUser(int userId)
        {
            var q = from p in DataContext.Select<Customer>()
                    join p1 in DataContext.Select<CustomerUser>() on p.Id equals p1.CustomerId
                    where p1.UserId == userId && p.ApproveStatus != ApprovalStatus.Disapproved
                    select p;
            return q.ToList();
        }

        /// <summary>
        /// 批量审批待审批客户
        /// </summary>
        /// <param name="customerIds">客户Id集合</param>
        /// <param name="isApproved">是否审批通过</param>
        /// <param name="approveComment">审批备注</param>
        /// <param name="approveBy">审批人</param>
        /// <returns></returns>
        public bool ApproveBatch(IEnumerable<int> customerIds, bool isApproved, string approveComment, string approveBy)
        {
            Customer obj = new Customer()
            {
                ApproveStatus = isApproved ? ApprovalStatus.Approved : ApprovalStatus.Disapproved,
                ApproveComment = approveComment,
                ApproveBy = approveBy,
                ApproveTime = DateTime.Now
            };
            int count = 0;
            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();

                    foreach (var customerId in customerIds)
                    {
                        int i = this.Update(obj, p => new { p.ApproveStatus, p.ApproveComment, p.ApproveBy, p.ApproveTime }, p => p.Id == customerId, exec);
                        count += i;
                    }
                    exec.CommitTransaction();
                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                }
            }
            return count > 0;
        }

        /// <summary>
        /// 获取指定审批状态且活动的客户集合
        /// </summary>
        /// <param name="status">审批状态</param>
        /// <returns>客户集合</returns>
        public List<Customer> GetByApprovalStatus(ApprovalStatus status)
        {
            var q = from p in DataContext.Select<Customer>()
                    where p.ApproveStatus == status && !p.IsDisable
                    select p;
            return q.ToList();
        }

        public List<Customer> GetChildren(int companyId)
        {
            var q = from p in DataContext.Select<Customer>()
                    where p.ParentId == companyId && !p.IsDisable
                    select p;
            return q.ToList();
        }


        public Customer GetOneByCode(string code)
        {
            var q = from p in DataContext.Select<Customer>()
                    where p.Code == code
                    select p;
            return q.First();
        }

        public List<Customer> GetEnable()
        {
            var q = from p in DataContext.Select<Customer>()
                    where !p.IsDisable
                    select p;
            return q.ToList();
        }

        public List<Customer> GetDisable()
        {
            var q = from p in DataContext.Select<Customer>()
                    where p.IsDisable
                    select p;
            return q.ToList();
        }

        public List<Customer> GetStartsWith(string keyword, bool isDisable)
        {
            if (isDisable)
            {
                var q = from p in DataContext.Select<Customer>()
                        where (p.Code.StartsWith(keyword) ||
                            p.NickName.StartsWith(keyword) ||
                            p.FullName.StartsWith(keyword))
                            && p.IsDisable
                        select p;
                return q.ToList();
            }
            else
            {
                var q = from p in DataContext.Select<Customer>()
                        where (p.Code.StartsWith(keyword) ||
                            p.NickName.StartsWith(keyword) ||
                            p.FullName.StartsWith(keyword))
                            && !p.IsDisable
                        select p;
                return q.ToList();
            }
        }

        public bool Enable(Customer t)
        {
            if (string.IsNullOrWhiteSpace(t.Code))
                throw new NoCodeSpecifiedException();

            t.IsDisable = false;
            int count = base.Update(t, p => new { IsDisable = p.IsDisable, p.ModifyBy, p.ModifyTime }, p => p.Code == t.Code);
            return (count > 0);
        }

        public bool Disable(Customer t)
        {
            if (string.IsNullOrWhiteSpace(t.Code))
                throw new NoCodeSpecifiedException();

            t.IsDisable = true;
            int count = base.Update(t, p => new { IsDisable = p.IsDisable, p.ModifyBy, p.ModifyTime }, p => p.Code == t.Code);
            return (count > 0);
        }

        public int RegisterWithUser(UserAccount userAccount, Customer customer, int applicationId)
        {
            FillRegisterDefault(customer);

            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();
                    UserAccountBLL ubll = new UserAccountBLL();
                    ubll.Insert<UserAccount>(userAccount, null, exec);
                    CustomerBLL cbll = new CustomerBLL();
                    cbll.Insert<Customer>(customer, null, exec);

                    CustomerUser cuser = new CustomerUser()
                    {
                        UserId = userAccount.Id,
                        CustomerId = customer.Id,
                        CreateBy = userAccount.CreateBy,
                    };
                    CustomerUserBLL cubll = new CustomerUserBLL();
                    cubll.Insert<CustomerUser>(cuser, null, exec);

                    // 创建用户和应用程序之间的关联
                    UserAccountApplication userApp = new UserAccountApplication()
                    {
                        UserId = userAccount.Id,
                        ApplicationId = applicationId,
                        CreateBy = userAccount.CreateBy
                    };
                    UserAccountApplicationBLL uabll = new UserAccountApplicationBLL();
                    uabll.Insert<UserAccountApplication>(userApp, null, exec);

                    exec.CommitTransaction();

                    return customer.Id;
                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                }
            }
        }

        private void FillRegisterDefault(Customer customer)
        {
            // 根据国家代码获得区域代码
            CountryBLL countrybll = new CountryBLL();
            Country country = countrybll.GetOneByCode(customer.CountryCode);
            string regionCode = (country != null) ? country.RegionCode : null;
            customer.RegionCode = regionCode;

            // 获得默认客户类型
            CustomerTypeBLL customerTypeBll = new CustomerTypeBLL();
            CustomerType customerType = customerTypeBll.GetRegisterDefault();
            customer.CustomerTypeId = customerType.Id;

            // 获得默认信用级别
            CreditClassBLL creditclassBll = new CreditClassBLL();
            CreditClass creditclass = creditclassBll.GetRegisterDefault();
            customer.CreditClassCode = creditclass.Code;
        }

        /// <summary>
        /// 更新自己的客户资料
        /// </summary>
        /// <param name="customer"></param>
        /// <returns></returns>
        public bool UpdateBySelf(Customer customer, string modifyBy)
        {
            customer.ModifyBy = modifyBy;

            int count = Update(customer,
                p => new
                {
                    p.NickName,
                    p.FullName,
                    p.Address1,
                    p.Address2,
                    p.Suburb,
                    p.City,
                    p.Province,
                    p.CountryCode,
                    p.ZipCode,
                    p.Email,
                    p.InMailList,
                    p.Mobile,
                    p.Phone,
                    p.Fax,
                    p.WebSite,
                    p.CourierAccountNo,
                    p.VatNo,
                    p.ModifyBy,
                    p.ModifyTime
                },
                p => p.Id == customer.Id);
            return count > 0;
        }

        /// <summary>
        /// 新增UserAmount与CustomerUser
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="CustomerId"></param>
        /// <param name="createBy"></param>
        /// <returns></returns>
        public int InsertCustomerUser(UserAccount entity, int CustomerId, string createBy)
        {
            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();
                    UserAccountBLL bll = new UserAccountBLL();
                    bll.Insert<UserAccount>(entity, null, exec);

                    CustomerUserBLL cbll = new CustomerUserBLL();
                    CustomerUser CUser = new CustomerUser();
                    CUser.UserId = entity.Id;
                    CUser.CustomerId = CustomerId;
                    CUser.CreateBy = createBy;
                    cbll.Insert<CustomerUser>(CUser, null, exec);

                    exec.CommitTransaction();

                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                }
                return entity.Id;
            }
        }



        /// <summary>
        /// 更新UserAmount与CustomerUser
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="CustomerId"></param>
        /// <param name="createBy"></param>
        /// <returns></returns>
        public bool UpdateByIdByUser(UserAccount entity, int CustomerId, string createBy)
        {
            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();
                    //更新UserAccount
                    UserAccountBLL bll = new UserAccountBLL();                
                    bll.UpdateById(entity, entity.Id);   
                    //更新Customer
                    CustomerUserBLL cbll = new CustomerUserBLL();
                    cbll.Delete(p => p.UserId == entity.Id,exec);//更新之前先删除
                    CustomerUser CUser = new CustomerUser();
                    CUser.UserId = entity.Id;
                    CUser.CustomerId = CustomerId;
                    CUser.CreateBy = createBy;
                    cbll.Insert<CustomerUser>(CUser, null, exec);
                    exec.CommitTransaction();

                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                 
                }
                return true;
            }
        }

    }
}
